﻿#region Namespace References

using System;
using DynConDevCorp.OpenArch.SmartData.Core;
using DynConDevCorp.OpenArch.SmartData.Interfaces;
using DynConDevCorp.OpenArch.SmartData.Interfaces.EventArgClasses;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UnitTest.DynConDevCorp.OpenArch.SmartData.Unit_Tests;

#endregion

namespace UnitTest.DynConDevCorp.OpenArch.SmartData
{
    /// <summary>
    ///This is a test class for SmartField_UnitTests and is intended
    ///to contain all SmartField_UnitTests Unit Tests
    ///</summary>
    [TestClass]
    public class SmartEntity_UnitTests
    {
        #region Public Instance Properties

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get { return testContextInstance; }
            set { testContextInstance = value; }
        }

        #endregion

        #region Public Instance Methods

        /// <summary>
        ///A test for Commit
        ///</summary>
        [TestMethod]
        public void Commit_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            target.EnableTrackChanges(true);
            target.Commit();
        }

        /// <summary>
        ///A test for ContainsField
        ///</summary>
        [TestMethod]
        public void ContainsField_UnitTest()
        {
            SmartEntity target = new TestSmartEntity();
            Assert.IsTrue(target.ContainsField("TestField1"));
            Assert.IsFalse(target.ContainsField("BogusField"));
        }


        /// <summary>
        ///A test for DataType
        ///</summary>
        [TestMethod]
        [ExpectedException(typeof (NotSupportedException))]
        public void DataType_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            Type dataType = target.DataType;
            Assert.IsNotNull(dataType);
        }


        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup]
        //public void MyTestCleanup()
        //{
        //}
        //

        [TestMethod]
        public void DisplayFormatter_UnitTest()
        {
            DisplayFormatter_UnitTestHelper<int>();
        }

        /// <summary>
        ///A test for DisplayFormatter
        ///</summary>
        public void DisplayFormatter_UnitTestHelper<DATA_TYPE>()
            where DATA_TYPE : IComparable<DATA_TYPE>
        {
            SmartField<DATA_TYPE> target = new SmartField<DATA_TYPE>();
            const ISmartDisplayFormatter<DATA_TYPE> expected = null;
            target.DisplayFormatter = expected;
            ISmartDisplayFormatter<DATA_TYPE> actual = target.DisplayFormatter;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for DisplayValue
        ///</summary>
        [TestMethod]
        [ExpectedException(typeof (NotSupportedException))]
        public void DisplayValue_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            const string expected = null;
            string actual = target.DisplayValue;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for EnableTrackChanges
        ///</summary>
        [TestMethod]
        public void EnableTrackChanges_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            Assert.IsFalse(target.TrackingChanges.ToBoolean());
            target.EnableTrackChanges(true);
            Assert.IsTrue(target.TrackingChanges.ToBoolean());
            target.EnableTrackChanges(false);
            Assert.IsFalse(target.TrackingChanges.ToBoolean());
        }

        /// <summary>
        ///A test for EntityID
        ///</summary>
        [TestMethod]
        public void EnitityID_UnitTest()
        {
            ISmartEntity target1 = new TestSmartEntity();
            ISmartEntity target2 = new TestSmartEntity();
            Assert.AreNotEqual(target1.EntityID, Guid.Empty);
            Assert.AreNotEqual(target2.EntityID, Guid.Empty);
            Assert.AreNotEqual(target1.EntityID, target2.EntityID);
        }

        /// <summary>
        ///A test for FieldCount
        ///</summary>
        [TestMethod]
        public void FieldCount_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            Assert.IsTrue(target.FieldCount > 0);
        }

        /// <summary>
        ///A test for Fields
        ///</summary>
        [TestMethod]
        [ExpectedException(typeof (NotImplementedException))]
        public void Fields_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            ISmartFieldKeyedCollection<String, ISmartField> fields = target.Fields;
            Assert.IsNotNull(fields);
            Assert.AreEqual(2, fields.Count);
            Assert.IsTrue(fields.Keys.Contains("TestField1"));
            Assert.AreSame(target.TestField1, fields["TestField1"]);
        }

        /// <summary>
        ///A test for FieldValueChanged()
        ///</summary>
        [TestMethod]
        public void FieldValueChanged_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            target.FieldValueChanged += target_FieldValueChanged;
            m_FieldValueChanged_Fired = false;
            target.TestField1.Value = 123;
            Assert.IsTrue(m_FieldValueChanged_Fired);
            target.FieldValueChanged -= target_FieldValueChanged;
        }

        /// <summary>
        ///A test for FormattedDisplay
        ///</summary>
        [TestMethod]
        [ExpectedException(typeof (NotSupportedException))]
        public void FormattedDisplay_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            string formatString = string.Empty;
            const string expected = "123";
            string actual = target.FormattedDisplay(formatString);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for RawValue (Get)
        ///</summary>
        [TestMethod]
        [ExpectedException(typeof (NotSupportedException))]
        public void GetRawValue_Get_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            object rawValue = target.RawValue;
            Assert.IsNotNull(rawValue);
        }

        /// <summary>
        ///A test for RawValue (Set)
        ///</summary>
        [TestMethod]
        [ExpectedException(typeof (NotSupportedException))]
        public void GetRawValue_Set_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            target.RawValue = new object();
        }

        /// <summary>
        ///A test for this[string]
        ///</summary>
        [TestMethod]
        public void IndexerByName_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            ISmartField field = target["TestField1"];
            Assert.AreSame(target.TestField1, field);
        }

        /// <summary>
        ///A test for InputInhibited
        ///</summary>
        [TestMethod]
        public void InputInhibited_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            target.InputInhibited = false;
            Assert.IsFalse(target.InputInhibited.ToBoolean());
            target.InputInhibited = true;
            Assert.IsTrue(target.InputInhibited.ToBoolean());
            target.TestField1.InputInhibited = false;
            Assert.AreEqual(target.InputInhibited, PartialBoolean.Mixed);
        }

        [TestMethod]
        public void InputParser_UnitTest()
        {
            InputParser_UnitTestHelper<int>();
        }

        /// <summary>
        ///A test for InputParser
        ///</summary>
        public void InputParser_UnitTestHelper<DATA_TYPE>()
            where DATA_TYPE : IComparable<DATA_TYPE>
        {
            SmartField<DATA_TYPE> target = new SmartField<DATA_TYPE>();
            const ISmartInputParser<DATA_TYPE> expected = null;
            target.InputParser = expected;
            ISmartInputParser<DATA_TYPE> actual = target.InputParser;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for InputValue
        ///</summary>
        [TestMethod]
        [ExpectedException(typeof (NotSupportedException))]
        public void InputValue_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            target.InputValue = "123";
        }

        /// <summary>
        ///A test for IsDirty
        ///</summary>
        [TestMethod]
        public void IsDirty_Mixed_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            target.EnableTrackChanges(true);
            target.TestField1.MarkAsDirty();
            bool isEntityDirty = target.IsDirty.ToBoolean();
            Assert.IsTrue(isEntityDirty);
        }

        /// <summary>
        ///A test for IsDirty
        ///</summary>
        [TestMethod]
        public void IsDirty_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            target.EnableTrackChanges(true);
            Assert.IsFalse(target.IsDirty.ToBoolean());
            target.MarkAsDirty();
            Assert.IsTrue(target.IsDirty.ToBoolean());
            target.Commit();
            Assert.IsFalse(target.IsDirty.ToBoolean());
        }

        /// <summary>
        ///A test for MarkAsDirty
        ///</summary>
        [TestMethod]
        public void MarkAsDirty_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            target.EnableTrackChanges(true);
            target.MarkAsDirty();
        }

        /// <summary>
        ///A test for OwningEntity
        ///</summary>
        [TestMethod]
        public void OwningEntity_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            ISmartEntity actual = target.OwningEntity;
            Assert.IsNull(actual);
        }

        /// <summary>
        ///A test for PeristanceState
        ///</summary>
        [TestMethod]
        public void PeristanceState_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            target.PersistenceState = SmartPersistenceState.ChangesPending;
            Assert.AreEqual(SmartPersistenceState.ChangesPending, target.PersistenceState);
        }


        /// <summary>
        ///A test for RawValue
        ///</summary>
        [TestMethod]
        [ExpectedException(typeof (NotSupportedException))]
        public void RawValue_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            object expected = 123;
            target.RawValue = expected;
            object actual = target.RawValue;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for RawValueChanged()
        ///</summary>
        [TestMethod]
        [ExpectedException((typeof (NotSupportedException)))]
        public void RawValueChanged_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            target.RawValueChanged += target_RawValueChanged;
            m_RawValueChanged_Fired = false;
            target.RawValue = 123;
            Assert.IsTrue(m_RawValueChanged_Fired);
            target.RawValueChanged -= target_RawValueChanged;
        }


        /// <summary>
        ///A test for WriteLocked
        ///</summary>
        [TestMethod]
        public void ReadOnly_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            target.WriteLocked = false;
            Assert.IsFalse(target.WriteLocked.ToBoolean());
            target.WriteLocked = true;
            Assert.IsTrue(target.WriteLocked.ToBoolean());
            target.TestField1.WriteLocked = false;
            Assert.AreEqual(target.WriteLocked, PartialBoolean.Mixed);
        }

        /// <summary>
        ///A test for Rollback
        ///</summary>
        [TestMethod]
        public void RollBack_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            target.EnableTrackChanges(true);
            target.Rollback();
        }

        /// <summary>
        ///A test for SetOwningEntity
        ///</summary>
        [TestMethod]
        public void SetOwningEntity_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            target.SetOwningEntity(null);
        }

        /// <summary>
        ///A test for SetRawFieldValue
        ///</summary>
        [TestMethod]
        public void SetRawFieldValue_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            const int expected = 123;
            target.SetRawFieldValue("TestField1", expected);
            Assert.AreEqual(expected, target.TestField1.Value);
        }

        /// <summary>
        ///A test for SmartField Constructor
        ///</summary>
        [TestMethod]
        public void SmartFieldConstructor_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            Assert.IsNotNull(target);
        }

        [TestMethod]
        public void SmartFieldConstructor_UnitTest1()
        {
            SmartFieldConstructor_UnitTest1Helper<int>();
        }

        /// <summary>
        ///A test for SmartField`1 Constructor
        ///</summary>
        public void SmartFieldConstructor_UnitTest1Helper<DATA_TYPE>()
            where DATA_TYPE : IComparable<DATA_TYPE>
        {
            SmartField<DATA_TYPE> target = new SmartField<DATA_TYPE>();
            Assert.IsNotNull(target);
        }

        /// <summary>
        ///A test for ToString()
        ///</summary>
        [TestMethod]
        public void ToString_UnitTest()
        {
            ISmartEntity target = new TestSmartEntity();
            String actual = target.ToString();
            Assert.IsNotNull(actual);
        }

        /// <summary>
        ///A test for TrackingChanges
        ///</summary>
        [TestMethod]
        [ExpectedException(typeof (ArgumentException))]
        public void TrackingChanges_Mixed1_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            target.TestField1.EnableTrackChanges(true);
            Assert.IsTrue(target.TrackingChanges.ToBoolean());
        }

        /// <summary>
        ///A test for TrackingChanges
        ///</summary>
        [TestMethod]
        public void TrackingChanges_Mixed2_UnitTest()
        {
            TestSmartEntity target = new TestSmartEntity();
            target.TestField1.EnableTrackChanges(true);
            Assert.AreEqual(target.TrackingChanges, PartialBoolean.Mixed);
        }

        [TestMethod]
        public void Value_UnitTest()
        {
            Value_UnitTestHelper<int>();
        }

        /// <summary>
        ///A test for Value
        ///</summary>
        public void Value_UnitTestHelper<DATA_TYPE>()
            where DATA_TYPE : IComparable<DATA_TYPE>
        {
            SmartField<DATA_TYPE> target = new SmartField<DATA_TYPE>();
            DATA_TYPE expected = default(DATA_TYPE);
            target.Value = expected;
            DATA_TYPE actual = target.Value;
            Assert.AreEqual(expected, actual);
        }

        #endregion

        #region Private Instance Methods

        private void target_FieldValueChanged(object sender, FieldValueChangedEventArgs e)
        {
            m_FieldValueChanged_Fired = true;
        }


        private void target_RawValueChanged(object sender, ValueChangedEventArgs<object> e)
        {
            m_RawValueChanged_Fired = true;
        }

        #endregion

        #region Fields and Constants

        private bool m_FieldValueChanged_Fired;
        private bool m_RawValueChanged_Fired;

        private TestContext testContextInstance;

        #endregion
    }
}